#ifndef __CAPAINDICES_SECUENCIAL_CPP
#define __CAPAINDICES_SECUENCIAL_CPP

/*****************************************************************************
*                     Organizacion de Datos - 75.06                          *
*                         Catedra Lic. Servetto                              *
*            Facultad de Ingenieria - Universidad de Buenos Aires            *
******************************************************************************/

#include "../Comun/Archivo.h"

#include "Secuencial.h"
#include "Indices.h"
#include "ArchivoRF.h"
#include "ArchivoRLV.h"

#include <iostream>

using namespace std;
using namespace Comun;

namespace CapaIndices
{
	
	/// Constructor
	/// @param metadatosIndice Metadatos necesarios para crear el indice.
	Secuencial::Secuencial(MetadatosIndice* metadatosIndice)
	{
		this->Metadata = metadatosIndice;
		
		if (metadatosIndice->TipoDato == Monovalente)
		{
			this->archivoDatos = new ArchivoRF(metadatosIndice->NombreClase);
		}	
		else if (metadatosIndice->TipoDato == Polivalente)
		{
			this->archivoDatos = new ArchivoRLV(metadatosIndice->NombreClase);
		}
		else
		{
			cerr << "CapaIndices->Secuencial.cpp->Secuencial::Secuencial(MetadatosIndice* metadatosIndice)" << endl << "No se reconoce el tipo de datos del indice." << endl;
			throw exception();
		}
	};
	
	/// Destructor
	Secuencial::~Secuencial()
	{
		delete this->archivoDatos;
	};
	
	/// Crea un nuevo indice a partir de la metadata suministrada.
	/// @return true si la creacion fue exitosa, sino false.
	bool Secuencial::Crear()
	{
		return true;
	};
	
	/// Inserta 'clave' en el inidce.
	/// @param clave La clave a insertar.
	void Secuencial::InsertarClave(Clave* clave)
	{
		cerr << "CapaIndices->Secuencial.cpp->Secuencial::InsertarClave(Clave* clave)" << endl << "El indice secuencial no soporta inserciones." << endl;
		throw exception();
	};
	
	/// Busca el registro representado por 'clave' y le asigna sus campos.
	/// @param clave La clave a buscar.
	void Secuencial::BuscarClave(Clave* clave)
	{
		int idGrupo = archivoDatos->PrimerGrupo();
		
		while(idGrupo != NoHayMasGrupos)
		{
			Grupo grupoActual = archivoDatos->LeerGrupo(idGrupo);
			
			for (IteradorDeRegistros i = grupoActual.Registros.begin(); i!= grupoActual.Registros.end() ; i++)
			{
				// Verifica que se cumplan otras condiciones
				if (clave->OtrasCondiciones->Analizar(*i))
				{
					clave->Resultado->insert(clave->Resultado->end(),*i);
					clave->RegistrosAfectados++;
				}
			}
			
			idGrupo = archivoDatos->SiguienteGrupo(idGrupo);
			clave->FlushResultados(false);
		}
	};
	
	/// Elimina el registro representado por 'clave'.
	/// @param clave La clave a eliminar.
	void Secuencial::EliminarClave(Clave* clave)
	{
		cerr << "CapaIndices->Secuencial.cpp->Secuencial::EliminarClave(Clave* clave)" << endl << "El indice secuencial no soporta eliminaciones." << endl;
		throw exception();
	};
	
	/// Actualiza los cambios producidos al registro representado por 'clave'.
	/// @param clave La clave a actualizar.
	void Secuencial::ActualizarClave(Clave* clave)
	{
		cerr << "CapaIndices->Secuencial.cpp->Secuencial::ActualizarClave(Clave* clave)" << endl << "El indice secuencial no soporta actualizaciones." << endl;
		throw exception();
	};
	
}

#endif
